package uml.GUI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.EnumSet;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

import net.miginfocom.swing.MigLayout;

import uml.controller.Controller;
import uml.eventsystem.IObserver;
import uml.eventsystem.ISubject;
import uml.eventsystem.SubjectImpl;
import uml.eventsystem.events.UMLEventId;
import uml.objects.UMLObject;
import uml.util.listeners.DragListener;
import uml.view.ClassFormatter_View;
import uml.view.UMLContainerView;
import uml.view.factory.ClassFormatterFactory;
import uml.view.factory.ContainerFactory;
import uml.view.factory.UMLContainerFactory;

public class ControlPalatte extends JPanel implements ActionListener, ISubject
{
	EnumSet<UMLEventId> registeredEvents = EnumSet.allOf(UMLEventId.class);
	SubjectImpl subjectImplementation = new SubjectImpl();
	/**
	 * Creates a default <tt>ControlPalatte</tt> 
	 * @param controller
	 */
	public ControlPalatte(Controller controller)
	{
		ClassFormatter_View umlObject = initFormatter("ClassBox");
		setLayout (new MigLayout ("wrap 1", "[align center]"));
		addButton(umlObject, UMLEventId.MAKE_CLASS);
		addButton(umlObject, UMLEventId.MAKE_NOTE);
		addButton(umlObject, UMLEventId.MAKE_PACKAGE);
		registerForEvents(controller);
	}
	/**
	 * creates a <tt>UMLObjectButton</tt> with an image of umlObject and an <tt>UMLEventId</tt> of event
	 * @param umlObject
	 * @param event
	 */
	private void addButton(UMLObject umlObject, UMLEventId event)
	{
		UMLObjectButton button;
		synchronized(umlObject.getTreeLock())
		{
			button = new UMLObjectButton(umlObject, event);
		}
		button.addActionListener(this);
		registeredEvents.add(event);
		add(button);
	}
	/**
	 * registers observer for all events that this object has
	 * @param observer
	 */
	private void registerForEvents(IObserver observer) {
		for(UMLEventId event : registeredEvents)
			addObserver(observer, event);
	}
	/**
	 * Used for testing purposes
	 * Creates a default class object to use as a button
	 * @param name
	 * @return
	 */
	private static ClassFormatter_View initFormatter (String name)
	{
		ClassFormatter_View formatter = new ClassFormatter_View ();
		formatter.setContainer(initContainer(name));
		formatter.getContainer().setSize(100,100);
		return formatter;
	}
	/**
	 * Used for testing purposes
	 * Creates a defualt container
	 * @param name
	 * @return
	 */
	private static UMLContainerView initContainer (String name)
	{
		UMLContainerView container = new UMLContainerView ();
		container.setSize (50, 20);
		container.addDragListener (new DragListener (container));
		BoxLayout layout = new BoxLayout (container, BoxLayout.Y_AXIS);
		Border b = BorderFactory.createTitledBorder (BorderFactory.createEtchedBorder (), name, TitledBorder.CENTER,
				TitledBorder.TOP);
		container.setBorder (b);
		container.setLayout (layout);
		container.setBackground (Color.green);
		container.addFields (3);
		
		return container;
	}
	
	@Override
	public void addObserver(IObserver observer, UMLEventId eventId) {
		subjectImplementation.addObserver(observer, eventId);
		
	}

	@Override
	public void removeObserver(IObserver observer, UMLEventId eventId) {
		subjectImplementation.removeObserver(observer, eventId);		
	}

	@Override
	public void notifyObservers(UMLEventId eventId) {
		subjectImplementation.notifyObservers(eventId);		
	}

	@Override
	public void actionPerformed(ActionEvent action) 
	{
		 UMLObjectButton button = (UMLObjectButton) action.getSource();
         notifyObservers(button.getUMLEventId());
	}
}